package re;

import fa.FARule;
import nfa.NFADesign;
import nfa.NFARulebook;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author haoly
 * @title Concatenate
 * @date 2025/4/17 08:51
 * @description 拼接正则表达式
 */
public class Concatenate<T extends Pattern> extends Pattern{
    private final T first;

    private final T second;

    public Concatenate(T first, T second) {
        this.first = first;
        this.second = second;
    }

    @Override
    public int precedence() {
        return 1;
    }

    @Override
    public NFADesign toNFADesign() {
        NFADesign firstNFADesign = first.toNFADesign();
        NFADesign secondNFADesign = second.toNFADesign();

        Object startState = firstNFADesign.getStartState();
        Set acceptStates = secondNFADesign.getAcceptStates();

        List<FARule> rules = new ArrayList<>();
        rules.addAll(firstNFADesign.getRulebook().getRules());
        rules.addAll(secondNFADesign.getRulebook().getRules());
        List<FARule> freeMoves = new ArrayList<>();
        for (Object state : firstNFADesign.getAcceptStates()) {
            FARule freeMove = new FARule(state, null, secondNFADesign.getStartState());
            freeMoves.add(freeMove);
        }
        rules.addAll(freeMoves);

        NFARulebook rulebook = new NFARulebook(rules);
        return new NFADesign(startState, acceptStates, rulebook);
    }

    @Override
    public String toString() {
        return first.bracket(this.precedence()) + "" + second.bracket(this.precedence());
    }
}
